home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-06-12 | 31.4 KB | 1,344 lines |
- /*
- Pencil V1.0, Copyright 1994, 95 by Florian Marquardt.
- This program may be distributed under the terms of the GNU general
- public license (Start Pencil and select "Info>COPYING..." for a copy of the
- license).
- */
- #import "PencilView.h"
- #import "PencilGraphic.h"
- #import "MultipleSelection.h"
- #import "Group.h"
- #import "PencilImage.h"
- #import "PencilText.h"
-
- #define EX te->location.x
- #define EY te->location.y
-
- #define EDITED if(!edited) { edited=YES; [window setDocEdited:YES]; }
-
- BOOL movementStatus=0; // currently moving a graphic? (EPS images only redrawn when move finished)
- extern BOOL globalTermination;
- id globalText=nil; // used for drawing RichText
- NXStream *result=NULL; // used for passing results to the TCL interpreter (PencilTCLClient)
-
- float *fpts=NULL; // array for points for freehand drawing... global since there is only one mouse
- int maxfpts=200; // arraysize=2*maxfpts*sizeof(float)
- float athresh, sumthresh;
-
- @implementation PencilView
- - initFrame:(const NXRect *)re
- {
- [super initFrame:re];
- glist=[[List alloc] init];
- scale=100;
- if(fpts==NULL)
- { fpts=(float *)malloc(sizeof(float)*2*maxfpts); }
- if(!globalText)
- {
- globalText=[[Text alloc] init];
- [globalText setMonoFont:NO];
- [globalText setEditable:NO];
- [globalText setSelectable:NO];
- [globalText setFlipped:YES];
- [globalText setClipping:NO];
- }
- if(flippedView=[[View alloc] initFrame:&bounds]) // for RichText editing
- {
- [flippedView setFlipped:YES];
- }
- return self;
- }
-
- - (BOOL)acceptsFirstResponder { return YES; }
-
- - awakeFromNib
- {
- [window makeKeyAndOrderFront:self];
- [inspector inspectForView:self];
- return self;
- }
-
- - free
- {
- int i;
-
- if(glist) {
- i=[glist count];
- while(i--) [[glist objectAt:i] free];
- [glist free];
- }
- if(customDef) free(customDef);
- if(docname) free(docname);
- return [super free];
- }
-
- - (BOOL)acceptsFirstMouse { return YES; }
-
- - drawSelf:(const NXRect *)re:(int)co
- {
- int i,c; id g;
-
- if(!initialized || NXDrawingStatus!=NX_DRAWING)
- {
- char filename[300];
- NXStream *stream;
- char *buffer;
- long l;
-
- strcpy(filename, [[NXBundle mainBundle] directory]);
- strcat(filename, "/../pencilDefinitions.ps");
- stream=NXMapFile(filename, NX_READONLY);
- if(!stream)
- {
- strcpy(filename, [[NXBundle mainBundle] directory]);
- strcat(filename, "/pencilDefinitions.ps");
- stream=NXMapFile(filename, NX_READONLY);
- }
- if(stream)
- {
- NXSeek(stream,0,NX_FROMEND);
- buffer=(char *)malloc(sizeof(char)*(l=NXTell(stream)+1));
- NXSeek(stream,0,NX_FROMSTART);
- NXRead(stream,buffer,l-1);
- NXClose(stream);
- buffer[l-1]=0;
- DPSPrintf(DPSGetCurrentContext()," %s\n",buffer);
- free(buffer);
- }
- else
- {
- NXRunAlertPanel("Alert", "Couldn't find pencilDefinitions.ps", "OK?!",NULL,NULL);
- [NXApp terminate:self];
- }
- if(NXDrawingStatus==NX_DRAWING)
- {
- strcpy(filename, [[NXBundle mainBundle] directory]);
- strcat(filename, "/../pencilControlProcDefinitions.ps");
- stream=NXMapFile(filename, NX_READONLY);
- if(!stream)
- {
- strcpy(filename, [[NXBundle mainBundle] directory]);
- strcat(filename, "/pencilControlProcDefinitions.ps");
- stream=NXMapFile(filename, NX_READONLY);
- }
- if(stream)
- {
- NXSeek(stream,0,NX_FROMEND);
- buffer=(char *)malloc(sizeof(char)*(l=NXTell(stream)+1));
- NXSeek(stream,0,NX_FROMSTART);
- NXRead(stream,buffer,l-1);
- NXClose(stream);
- buffer[l-1]=0;
- DPSPrintf(DPSGetCurrentContext()," %s\n",buffer);
- free(buffer);
- }
- else
- {
- NXRunAlertPanel("Alert", "Couldn't find pencilControlProcDefinitions.ps", "OK?!",NULL,NULL);
- [NXApp terminate:self];
- }
- }
- else
- if(customDef) DPSPrintf(DPSGetCurrentContext(), " %s\n ", customDef);
- if(NXDrawingStatus==NX_DRAWING) initialized=YES;
- }
- [window disableFlushWindow];
- PSsetgray(1);
- if(re) { NXRectClip(re); NXRectFill(re); } else NXRectFill(&bounds);
- c=[glist count];
- for(i=0;i<c;i++) if(![(g=[glist objectAt:i]) selected]) [g draw:re];
- [window reenableFlushWindow];
- return self;
- }
-
- - displayCurrentGraphic
- {
- if(currentGraphic)
- {
- [self lockFocus];
- PSsetinstance(YES);
- PSnewinstance();
- [currentGraphic drawControl:NULL:curPt:500/scale];
- PSsetinstance(NO);
- [self unlockFocus];
- }
- return self;
- }
-
- - displayWithCurrentGraphic
- {
- [self display];
- [self displayCurrentGraphic];
- return self;
- }
-
- - setCurrentGraphicAndDisplay:(id)gr
- {
- currentGraphic=gr;
- [self displayCurrentGraphic];
- return self;
- }
-
- #define IFCUR if(currentGraphic)
- #define CUR currentGraphic
-
- const char *txtinit="/text (Text) def /fontsize 32 def /font (Helvetica) def";
-
- #define ADJUST [self convertPoint:&te->location fromView:nil]
- - mouseDown:(NXEvent *)te
- {
- // command-click: create new graphic
- // click: if currentGraphic selected: select/move pts or move graphic
- // if not: try to select/move graphic
- // control-click: rotate
-
- if(!editingRichText)
- {
- if(te->flags & NX_COMMANDMASK) // create
- {
- char *mname; NXColor c1; NXColor c2; float lw; char *dm; char *fm; char *sm; char *ud; NXRect rec;
-
- EDITED;
- IFCUR { [CUR calculateBoundingBox:self]; [CUR giveBounds:&rec]; [CUR select:NO]; }
- else rec=bounds;
- [inspector giveSettings:&mname:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- if(!currentGraphic && !strncmp(mname,"charP", 5))
- {
- [inspector setUserDef:txtinit];
- ud=txtinit;
- }
- if(!strcmp(mname,"RT"))
- [glist addObject:CUR=[[[PencilText alloc] init] initWithSettings:mname:c1:c2:lw:dm:fm:sm:ud]];
- else
- [glist addObject:CUR=[[[PencilGraphic alloc] init] initWithSettings:mname:c1:c2:lw:dm:fm:sm:ud]];
- curGrPos=[glist count]-1;
- [CUR select:YES];
- [self display:&rec:1];
- // if RichText desired
- if(!strcmp(mname,"RT"))
- {
- editingRichText=YES;
- [self addSubview:flippedView];
- [flippedView setFrame:&bounds];
- [CUR editText:te:self:flippedView];
- }
- else
- {
- if([[[[[inspector creationType] target] itemList] selectedCell] tag]==1)
- {
- athresh=[[ inspector athreshField] floatValue];
- sumthresh=[[inspector sthreshField] floatValue];
- if(athresh<.1) athresh=1.5;
- if(sumthresh<.1) sumthresh=.9;
- [CUR createPolyFreehand:te:&curPt:self:500/scale];
- }
- else
- {
- [CUR create:te:&curPt:self:500/scale];
- }
- }
- }
- else // select graphic/point, move point
- {
- [self convertPoint:&te->location fromView:nil];
-
- IFCUR
- {
- if([CUR isMemberOf:[PencilText class]])
- {
- if(te->data.mouse.click==2) {
- editingRichText=YES;
- EDITED;
- [self addSubview:flippedView];
- [flippedView setFrame:&bounds];
- [CUR editText:te:self:flippedView];
- return self;
- }
- }
-
- if(!(te->flags & NX_CONTROLMASK)) { // not rotating/scaling
- // select pt, move it
- if([CUR move:te:&curPt:self:500/scale]) { EDITED; return self; }
- }
- }
-
- { // select graphic
- int i, selCount=0;
- id curcur=currentGraphic;
-
- if(!CUR && !(te->flags & NX_CONTROLMASK)) te->flags&=(~NX_SHIFTMASK);
- if(CUR && ![CUR isMemberOf:[MultipleSelection class]] && (!(te->flags&NX_SHIFTMASK) || (te->flags & NX_CONTROLMASK)))
- {
- if((te->flags & NX_ALTERNATEMASK) && !(te->flags & NX_CONTROLMASK)) i=curGrPos; else i=curGrPos+1;
- while(i--) if([[glist objectAt:i] selected:te:&curPt:self]) break;
- if(i<0)
- {
- i=[glist count];
- while(--i>curGrPos) if([[glist objectAt:i] selected:te:&curPt:self]) break;
- if(i<=curGrPos) i=-1;
- }
- }
- else
- {
- id g;
-
- i=[glist count]; while(i--) { if([g=[glist objectAt:i] selected]) ++selCount; if([g selected:te:&curPt:self]) break; }
- }
- if(i>=0)
- {
- char *name; NXColor c1; NXColor c2; float lw; char *dm, *fm, *sm, *ud;
- NXRect rec; BOOL multipleSelChanged=NO;
-
- if((te->flags & NX_SHIFTMASK) && !(te->flags & NX_CONTROLMASK)) // multiple selection
- {
- if(![[glist objectAt:i] selected])
- {
- if(!CUR || ![CUR isMemberOf:[MultipleSelection class]])
- {
- IFCUR {
- CUR=[[MultipleSelection alloc] initWithGraphic:CUR];
- [CUR addToSelection:[[glist objectAt:i] select:YES] posFromEnd:selCount];
- }
- else
- {
- CUR=[[MultipleSelection alloc] initWithGraphic:[[glist objectAt:i] select:YES]];
- }
- }
- else
- [CUR addToSelection:[[glist objectAt:i] select:YES] posFromEnd:selCount];
- multipleSelChanged=YES;
- }
- }
- else
- {
- if(!CUR || ![CUR isMemberOf:[MultipleSelection class]] || ![[glist objectAt:i] selected])
- {
- CUR=[glist objectAt:i];
- curGrPos=i;
- [CUR select:YES];
- }
- }
- if(curcur!=CUR && curcur!=nil && (!multipleSelChanged || ![CUR partOfSelection:curcur]))
- {
- [curcur calculateBoundingBox:self];
- [curcur giveBounds:&rec];
- [curcur select:NO];
- [self display:&rec:1];
- }
- if(curcur!=CUR || multipleSelChanged)
- {
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&rec];
- [self display:&rec:1];
- }
- [self lockFocus];
- PSsetinstance(YES);
- if(curcur!=CUR || multipleSelChanged)
- {
- PSnewinstance();
- [currentGraphic drawControl:NULL:curPt:500/scale];
- }
- if(curcur!=CUR)
- {
- [CUR giveSettings:&name:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- [inspector takeSettings:name:c1:c2:lw:dm:fm:sm:ud];
- }
- { // moving/rotating/scaling the selection
-
- if(te->flags & NX_CONTROLMASK) // rotate or scale
- {
- if(te->flags & NX_SHIFTMASK) // scale
- {
- int oldMask;
- BOOL shouldLoop=YES;
- float dx,dy, oldscalex=1, oldscaley=1, newscalex, newscaley;
- NXEvent thisEvent;
-
- EDITED;
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- dx=te->location.x; dy=te->location.y;
-
- while (shouldLoop) {
- do {
- te = [NXApp getNextEvent:(NX_LMOUSEUPMASK |
- NX_LMOUSEDRAGGEDMASK)];
- } while(te->type==NX_LMOUSEDRAGGED && ([NXApp peekNextEvent:NX_LMOUSEDRAGGEDMASK into:&thisEvent]));
-
- ADJUST;
- newscalex=(EX-dx)/20+1;
- if(!(te->flags & NX_ALTERNATEMASK)) newscaley=newscalex; else newscaley=(EY-dy)/20+1;
- if(fabs(newscalex)<1e-3) newscalex=1e-3;
- if(fabs(newscaley)<1e-3) newscaley=1e-3;
- [CUR scaleCenter:dx:dy by:newscalex/oldscalex:newscaley/oldscaley];
- oldscalex=newscalex;
- oldscaley=newscaley;
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSflushgraphics();
- NXPing();
- if(te->type==NX_LMOUSEUP) shouldLoop=NO;
- }
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSflushgraphics();
- NXPing();
- PSsetinstance(NO);
- [self unlockFocus];
- [window setEventMask:oldMask];
- return self;
- }
- else
- {
- int oldMask;
- BOOL shouldLoop=YES;
- float dx,dy;
- BOOL placingHorizontal=YES;
- NXPoint pt0, pt1;
- NXEvent thisEvent;
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- dx=te->location.x; dy=te->location.y;
-
-
- while (shouldLoop) {
- do {
- te = [NXApp getNextEvent:(NX_LMOUSEUPMASK |
- NX_LMOUSEDRAGGEDMASK | NX_LMOUSEDOWNMASK)];
- } while(te->type==NX_LMOUSEDRAGGED && ([NXApp peekNextEvent:NX_LMOUSEDRAGGEDMASK into:&thisEvent]));
-
- ADJUST;
- if(placingHorizontal)
- {
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSsetgray(0);
- PSmoveto(dx-5,dy);
- PSrlineto(10,0); PSstroke();
- PSmoveto(dx, dy-5);
- PSrlineto(0,10); PSstroke();
- PSmoveto(dx,dy);
- PSlineto(te->location.x, te->location.y);
- PSstroke();
- PSflushgraphics();
- NXPing();
- }
- else
- {
- [CUR rotateAroundCenter:dx:dy fromPoint:&pt1 toPoint:&te->location];
- pt1=te->location;
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSsetgray(.5);
- PSmoveto(dx-5,dy);
- PSrlineto(10,0); PSstroke();
- PSmoveto(dx, dy-5);
- PSrlineto(0,10); PSstroke();
- PSmoveto(dx,dy);
- PSlineto(pt0.x, pt0.y);
- PSstroke();
- PSflushgraphics();
- NXPing();
- }
- if(te->type==NX_LMOUSEUP)
- {
- if(placingHorizontal)
- {
- placingHorizontal=NO;
- pt0=pt1=te->location;
- if(pt0.x==dx && pt0.y==dy) { pt0.x+=30; pt1=pt0; }
- }
- else
- shouldLoop=NO;
- }
- }
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSflushgraphics();
- NXPing();
- PSsetinstance(NO);
- [self unlockFocus];
- [window setEventMask:oldMask];
- return self;
- }
- }
- else
- {
- int oldMask;
- BOOL shouldLoop=YES;
- float dx,dy;
- NXEvent thisEvent;
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- dx=te->location.x; dy=te->location.y;
-
- while (shouldLoop) {
- do {
- te = [NXApp getNextEvent:(NX_LMOUSEUPMASK |
- NX_LMOUSEDRAGGEDMASK)];
- } while(te->type==NX_LMOUSEDRAGGED && ([NXApp peekNextEvent:NX_LMOUSEDRAGGEDMASK into:&thisEvent]));
-
- ADJUST;
- if(EX!=dx || EY!=dy)
- {
- movementStatus=1;
- EDITED;
- [CUR addTranslation:EX-dx:EY-dy];
- dx=EX; dy=EY;
- PSnewinstance();
- [CUR drawControl:NULL:curPt:500/scale];
- PSflushgraphics();
- NXPing();
- }
- if(te->type==NX_LMOUSEUP)
- shouldLoop=NO;
-
- }
- if(movementStatus) {
- movementStatus=0;
- [CUR drawIfNeeded:NULL:curPt:500/scale];
- }
- PSsetinstance(NO);
- [self unlockFocus];
- [window setEventMask:oldMask];
- }
- }
- }
- else // no graphic selected
- {
- IFCUR
- {
- NXRect rec;
-
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&rec];
- [CUR select:NO];
- CUR=nil; curGrPos=-1;
- [self display:&rec:1];
- [self lockFocus]; PSnewinstance(); [self unlockFocus];
- [inspector clearUserDef:nil];
- }
- // drag selection
- { int oldMask;
- BOOL shouldLoop=YES;
- float dx,dy;
- int c=[glist count];
- NXRect theSel, thebounds;
-
- oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
-
- dx=te->location.x; dy=te->location.y;
-
- [self lockFocus];
- PSsetinstance(YES);
-
- while (shouldLoop) {
- te = [NXApp getNextEvent:(NX_LMOUSEUPMASK |
- NX_LMOUSEDRAGGEDMASK)];
-
- ADJUST;
- if(EX!=dx || EY!=dy)
- {
- PSnewinstance();
- PSsetgray(.5);
- PSrectstroke(dx,dy,EX-dx,EY-dy);
- PSflushgraphics();
- }
- if(te->type==NX_LMOUSEUP)
- shouldLoop=NO;
-
- }
- PSsetinstance(NO);
- PSnewinstance();
- [self unlockFocus];
- [window setEventMask:oldMask];
-
- if(dx<EX) { theSel.origin.x=dx; theSel.size.width=EX-dx; } else { theSel.origin.x=EX; theSel.size.width=dx-EX; }
- if(dy<EY) { theSel.origin.y=dy; theSel.size.height=EY-dy; } else { theSel.origin.y=EY; theSel.size.height=dy-EY; }
- if(theSel.size.width!=0 && theSel.size.height!=0)
- {
- for(i=0;i<c;i++) {
- [[glist objectAt:i] giveBounds:&thebounds];
- if(NXIntersectsRect(&theSel, &thebounds))
- {
- IFCUR { [CUR addToSelection:[[glist objectAt:i] select:YES] posFromEnd:0]; }
- else
- { [CUR=[MultipleSelection alloc] initWithGraphic:[[glist objectAt:i] select:YES]];
- }
- }
- }
- IFCUR {
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&thebounds];
- [self display:&thebounds:1];
- [self displayCurrentGraphic];
- }
- }
- }
- }
- }
- }
- }
- else
- [window endEditingFor:self];
- return self;
- }
-
- - (BOOL)makeGroup
- {
- id oldcur;
-
- if(CUR && [CUR isMemberOf:[MultipleSelection class]])
- {
- EDITED;
- oldcur=CUR;
- [glist addObject:CUR=[[[Group alloc] initEmpty] select:YES]];
- [oldcur moveElementsFrom:glist to:[CUR slist]];
- [oldcur select:NO];
- return YES;
- }
- else
- return NO;
- }
-
- - ungroup
- {
- if(CUR && [CUR isKindOf:[Group class]])
- {
- id sl, old;
- int i,c,pos;
-
- EDITED;
- sl=[old=CUR slist];
- c=[sl count];
- pos=[glist indexOf:CUR];
- [glist removeObject:CUR];
- CUR=[[MultipleSelection alloc] initEmpty];
- [old addElementsTo:[CUR slist]];
- for(i=0;i<c;i++) [glist insertObject:[sl objectAt:i] at:pos+i];
- [old freeLeaveObjects];
- }
- return self;
- }
-
- - ungroup:sender
- {
- [self ungroup];
- [self displayWithCurrentGraphic];
- return self;
- }
-
- - makeStandardGroup:sender
- {
- if([self makeGroup])
- {
- [CUR setGroupType:PENCIL_STANDARD_GROUP];
- [self displayCurrentGraphic];
- }
- return self;
- }
-
- - makeClipGroup:sender
- {
- if([self makeGroup])
- {
- [CUR setGroupType:PENCIL_CLIP_GROUP];
- [self displayCurrentGraphic];
- }
- return self;
- }
-
- - deselectAll:sender
- {
- IFCUR
- {
- NXRect rec;
-
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&rec];
- [CUR select:NO];
- CUR=nil; curGrPos=-1;
- [self display:&rec:1];
- [self lockFocus]; PSnewinstance(); [self unlockFocus];
- [inspector clearUserDef:nil];
- }
- return self;
- }
- - selectAll:sender
- {
- int c=[glist count], i;
- NXRect thebounds;
-
- IFCUR { [CUR select:NO]; CUR=nil; curGrPos=-1; }
- for(i=0;i<c;i++) {
- IFCUR { [CUR addToSelection:[[glist objectAt:i] select:YES] posFromEnd:0]; }
- else
- { [CUR=[MultipleSelection alloc] initWithGraphic:[[glist objectAt:i] select:YES]]; }
- }
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&thebounds];
- NXIntersectionRect(&bounds,&thebounds);
- [self display:&thebounds:1];
- [self displayCurrentGraphic];
- return self;
- }
- - setMethodname:(char*)name { IFCUR { [CUR setMethodname:name]; EDITED; } return [self displayCurrentGraphic]; }
- - setDrawingMethod:(char *)name { IFCUR { [CUR setDrawingMethod:name]; EDITED; } return [self displayCurrentGraphic]; }
- - setStrokeMethod:(char *)name { IFCUR { [CUR setStrokeMethod:name]; EDITED; } return [self displayCurrentGraphic]; }
- - setFillMethod:(char *)name { IFCUR { [CUR setFillMethod:name]; EDITED; } return [self displayCurrentGraphic]; }
- - setSpecialAttributes:(char *)name { IFCUR { [CUR setSpecialAttributes:name]; EDITED; } return [self displayCurrentGraphic]; }
- - setColor1:(NXColor)col { IFCUR { [CUR setColor1:col]; EDITED; } return [self displayCurrentGraphic];}
- - setColor2:(NXColor)col { IFCUR { [CUR setColor2:col]; EDITED; } return [self displayCurrentGraphic]; }
- - setLineWidth:(float)lw { IFCUR { [CUR setLineWidth:lw]; EDITED; } return [self displayCurrentGraphic]; }
- - changeScale:sender
- {
- float sc;
-
- sc=atoi([[sender selectedCell] title]);
- if(sc>0)
- {
- float x,y,w,h;
- x=bounds.origin.x;
- y=bounds.origin.y;
- w=bounds.size.width;
- h=bounds.size.height;
- [self scale:sc/scale:sc/scale];
- [self translate: bounds.origin.x-(x+w/2-bounds.size.width/2):bounds.origin.y-(y+h/2-bounds.size.height/2)];
- scale=sc;
- [self display];
- [self displayCurrentGraphic];
- }
- return self;
- }
- - scroll:sender
- {
- switch([sender tag])
- {
- case 0: [self translate:0:bounds.size.height*[scrollFactor floatValue]]; break;
- case 1: [self translate:0:bounds.size.height*(-[scrollFactor floatValue])]; break;
- case 2: [self translate:bounds.size.width*(-[scrollFactor floatValue]):0]; break;
- case 3: [self translate:bounds.size.width*[scrollFactor floatValue]:0]; break;
- }
- [self display];
- [self displayCurrentGraphic];
- return self;
- }
- - toFront:sender
- {
- IFCUR
- {
- EDITED;
- if([CUR isMemberOf:[MultipleSelection class]])
- [CUR toFrontIn:glist];
- else
- {
- if(curGrPos!=[glist count]-1)
- {
- [glist removeObjectAt:curGrPos];
- [glist addObject:currentGraphic];
- }
- }
- }
- return self;
- }
- - toBack:sender
- {
- IFCUR
- {
- EDITED;
- if([CUR isMemberOf:[MultipleSelection class]])
- [CUR toBackIn:glist];
- else
- {
- if(curGrPos!=0)
- {
- [glist removeObjectAt:curGrPos];
- [glist insertObject:currentGraphic at:0];
- }
- }
- }
- return self;
- }
- - insertPoint:sender
- {
- IFCUR { EDITED; [(PencilGraphic *)currentGraphic insertPoint:&curPt]; [self displayCurrentGraphic]; }
- return self;
- }
- - insertNextPoint:sender
- {
- IFCUR { EDITED; [(PencilGraphic *)currentGraphic insertNextPoint:&curPt]; [self displayCurrentGraphic]; }
- return self;
- }
- - deletePoint:sender
- {
- IFCUR { EDITED; [(PencilGraphic *)currentGraphic deletePoint:&curPt]; [self displayCurrentGraphic]; }
- return self;
- }
-
- - insertThreePoints:sender
- {
- IFCUR { EDITED; [(PencilGraphic *)currentGraphic insertThreePoints:&curPt]; [self displayCurrentGraphic]; }
- return self;
- }
- - alignThreePoints:sender
- {
- IFCUR { EDITED; [(PencilGraphic *)currentGraphic alignThreePoints:&curPt]; [self displayCurrentGraphic]; }
- return self;
- }
-
- - keyDown:(NXEvent *)te
- {
- if(te->data.key.charCode==127)
- [self deleteGraphic:self];
- else
- {
- switch((char)(te->data.key.charCode))
- {
- case '8': [self translate:0:bounds.size.height*[scrollFactor floatValue]]; break;
- case '2': [self translate:0:bounds.size.height*(-[scrollFactor floatValue])]; break;
- case '4': [self translate:bounds.size.width*(-[scrollFactor floatValue]):0]; break;
- case '6': [self translate:bounds.size.width*[scrollFactor floatValue]:0]; break;
- case ' ' :
- case 13: return [self paste:self:YES]; break;
- }
- [self display];
- [self displayCurrentGraphic];
- }
- return self;
- }
-
- - deleteGraphic:sender
- {
- IFCUR { EDITED; if([CUR isMemberOf:[MultipleSelection class]])
- [CUR deleteThemIn:glist]; else [glist removeObjectAt:curGrPos]; curGrPos=-1; currentGraphic=nil; [self lockFocus]; PSnewinstance(); [self unlockFocus]; }
- return self;
- }
-
- - writeDoc:(NXTypedStream *)stream
- {
- int n, i;
- NXRect wframe;
-
- [window getFrame:&wframe];
- NXWriteRect(stream, &wframe);
- NXWriteRect(stream, &bounds);
- NXWriteRect(stream, &frame);
- n=[glist count];
- NXWriteTypes(stream,"f*i",&scale, &customDef, &n);
- for(i=0;i<n;i++)
- NXWriteRootObject(stream, [glist objectAt:i]);
- return self;
- }
-
- - readDoc:(NXTypedStream *)stream
- {
- int n;
- NXRect nbounds, nframe, wframe;
-
- NXReadRect(stream, &wframe);
- NXReadRect(stream, &nbounds);
- NXReadRect(stream, &nframe);
- NXReadTypes(stream,"f*i",&scale, &customDef,&n);
- [glist=[List alloc] setAvailableCapacity:n];
- while(n--) [glist addObject:NXReadObject(stream)];
- [window placeWindow:&wframe];
- // [self setFrame:&nframe];
- [self setDrawSize:nbounds.size.width:nbounds.size.height];
- [self setDrawOrigin:nbounds.origin.x: nbounds.origin.y];
- return self;
- }
-
- - doSave:(char *)filename
- {
- NXTypedStream *st;
-
- if(st=NXOpenTypedStreamForFile(filename, NX_WRITEONLY))
- {
- edited=NO;
- [window setDocEdited:NO];
- [self writeDoc:st];
- NXCloseTypedStream(st);
- }
- return self;
- }
-
- - saveAs:sender
- {
- [[SavePanel new] setRequiredFileType:"pencil"];
- if([[SavePanel new] runModal]==NX_OKTAG)
- {
- if([[SavePanel new] filename])
- {
- if(docname) free(docname);
- docname=(char *)malloc(sizeof(char)*(strlen([[SavePanel new] filename])+1));
- strcpy(docname, [[SavePanel new] filename]);
- [window setTitleAsFilename:docname];
- [self doSave:docname];
- }
- }
- return self;
- }
-
- - save:sender
- {
- if(docname) [self doSave:docname]; else [self saveAs:sender];
- return self;
- }
-
- - readFromFilename:(char *)name
- {
- int i;
- NXStream *st;
-
- if(st=NXOpenTypedStreamForFile(name, NX_READONLY))
- {
- if(glist) {
- i=[glist count];
- while(i--) [[glist objectAt:i] free];
- [glist free];
- }
- if(customDef) free(customDef);
- if(docname) free(docname);
- docname=(char *)malloc(sizeof(char)*(strlen(name)+1));
- strcpy(docname, name);
- [window setTitleAsFilename:docname];
- [self readDoc:st];
- NXCloseTypedStream(st);
- [self sendCustom];
- // [self display];
- [window display];
- }
- return self;
- }
-
- - windowDidBecomeMain:sender
- {
- char *name; NXColor c1; NXColor c2; float lw; char *dm, *fm, *sm, *ud;
-
- [inspector inspectForView:self];
- IFCUR { [CUR giveSettings:&name:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- [inspector takeSettings:name:c1:c2:lw:dm:fm:sm:ud];
- }
- return self;
- }
-
- - windowWillClose:sender
- {
- int ch;
-
- if(!globalTermination)
- {
- if(edited)
- {
- if(docname)
- ch=NXRunAlertPanel("Close Document", "Do you want to save \"%s\" before closing it?", "Save","Don't save","Cancel", docname);
- else
- ch=NXRunAlertPanel("Close Document", "Do you want to save the yet unnamed document before closing it?", "Save","Don't save","Cancel");
- switch(ch)
- {
- case 0: [inspector viewVanished:self]; return self;
- case 1: [self save:self]; [inspector viewVanished:self]; return self;
- case -1: return nil;
- }
- }
- }
- else
- {
- if(edited)
- {
- if(docname)
- ch=NXRunAlertPanel("Close Document", "Do you want to save \"%s\" before quitting?", "Save","Don't save","Cancel", docname);
- else
- ch=NXRunAlertPanel("Close Document", "Do you want to save the yet unnamed document before quitting?", "Save","Don't save","Cancel");
- switch(ch)
- {
- case 0: [inspector viewVanished:self]; return self;
- case 1: [self save:self]; [inspector viewVanished:self]; return self;
- case -1: globalTermination=NO; return nil;
- }
- }
- }
- [inspector viewVanished:self]; return self;
- }
-
- -copy:sender
- {
- const char *const types[1] = {"PencilPBoardType"};
- id pb = [Pasteboard new];
- char *data;
- int length;
-
- if(currentGraphic)
- {
- [CUR calculateBoundingBox:self];
- [pb declareTypes:types num:1 owner:nil];
- data = NXWriteRootObjectToBuffer(currentGraphic, &length);
- [pb writeType:types[0] data:data length:length];
- NXFreeObjectBuffer(data, length);
- }
- return self;
- }
-
- - copyAsPostScript:sender
- {
- const char *const types[1] = {NXPostScriptPboardType};
-
- [self deselectAll:self];
- [[Pasteboard new] declareTypes:types num:1 owner:nil];
- [self writePSCodeInside:&bounds to:[Pasteboard new]];
- return self;
- }
-
- - cut:sender
- {
- [self copy:sender];
- [self deleteGraphic:sender];
- return self;
- }
-
- - paste:sender
- {
- return [self paste:sender:NO]; // no centering
- }
-
- -paste:sender:(BOOL)flag
- {
- char **type;
- id pb = [Pasteboard new];
- char *data;
- int length;
-
- for(type = [pb types];*type;type++) {
- if(!strcmp(*type,"PencilPBoardType"))
- break;
- }
- if(*type) {
- char *name; NXColor c1; NXColor c2; float lw; char *dm, *fm, *sm, *ud;
-
- IFCUR
- {
- NXRect rec;
-
- [CUR calculateBoundingBox:self];
- [CUR giveBounds:&rec];
- [CUR select:NO];
- CUR=nil;
- curGrPos=-1;
- [self display:&rec:1];
- [self lockFocus]; PSnewinstance(); [self unlockFocus];
- }
-
- [pb readType:*type data:&data length:&length];
- currentGraphic =NXReadObjectFromBuffer(data, length);
- if([CUR isMemberOf:[MultipleSelection class]])
- [CUR addElementsTo:glist];
- else
- [glist addObject:CUR];
- NXFreeObjectBuffer(data, length);
- if(flag)
- {
- NXPoint c;
-
- [window getMouseLocation:&c];
- [self convertPoint:&c fromView:nil];
- [CUR centerAt:&c];
- }
- else
- [currentGraphic addTranslation:-10:-10];
- curGrPos=[glist count]-1;
- [CUR select:YES];
- [self lockFocus];
- PSsetinstance(YES);
- PSnewinstance();
- [currentGraphic drawControl:NULL:curPt:500/scale];
- [CUR giveSettings:&name:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- [inspector takeSettings:name:c1:c2:lw:dm:fm:sm:ud];
- PSsetinstance(NO);
- [self unlockFocus];
- EDITED;
- }
- return self;
- }
-
- - sendCustom
- {
- [self lockFocus];
- DPSPrintf(DPSGetCurrentContext(), " %s\n ", customDef);
- [self unlockFocus];
- return self;
- }
-
- - takeCustomFrom:(id)text
- {
- if(customDef) free(customDef);
- customDef=(char *)malloc(sizeof(char)*([text textLength]+1));
- [text getSubstring:customDef start:0 length:[text textLength]+1];
- [self sendCustom];
- [self display];
- EDITED;
- return self;
- }
-
- - giveCustomTo:(id)text
- {
- [text setText:(const char *)customDef];
- return self;
- }
-
- - importImage:sender
- {
- const char *types[]={ "tiff", "eps", "rib", NULL };
-
- if([[OpenPanel new] runModalForTypes:types]==NX_OKTAG)
- {
- [self importImageFromFile:[[OpenPanel new] filename]:bounds.origin.x+5:bounds.origin.y+5];
- [self displayCurrentGraphic];
- }
- return self;
- }
-
- - importImageFromFile:(char *)name:(float)posx:(float)posy
- {
- char *mname; NXColor c1; NXColor c2; float lw; char *dm; char *fm; char *sm; char *ud;
- [self deselectAll:self];
- [inspector giveSettings:&mname:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- if(CUR=[[PencilImage alloc] initFromFile:name])
- {
- curGrPos=[glist count];
- [glist addObject:CUR];
- [CUR select:YES];
- [CUR initWithSettings:mname:c1:c2:lw:dm:fm:sm:ud];
- [CUR addTranslation:posx:posy];
- [CUR calculateBoundingBox:self];
- EDITED;
- }
- return self;
- }
-
- - richTextEnded:sender
- {
- editingRichText=NO;
- [flippedView removeFromSuperview];
- return self;
- }
-
- - convertToCharPath:sender
- {
- IFCUR {
- // is it a RichText?
- if([currentGraphic isKindOf:[PencilText class]])
- {
- id newtxt;
- char *mname; NXColor c1; NXColor c2; float lw; char *dm, *fm, *sm, *ud;
-
- EDITED;
- newtxt=[[PencilGraphic alloc] init];
- [CUR makeCharacterPath: self: newtxt]; // RichTxt will initialize CharP
- [glist addObject:newtxt];
- [self deleteGraphic:self];
- CUR=newtxt;
- curGrPos=[glist count]-2;
- [CUR select:YES];
- [self displayWithCurrentGraphic];
- {
- [CUR giveSettings:&mname:&c1:&c2:&lw:&dm:&fm:&sm:&ud];
- [inspector takeSettings:mname:c1:c2:lw:dm:fm:sm:ud];
- }
- }
- }
- return self;
- }
-
- - (char *)performCommand:(const char *)cmd
- {
- static char resStr[20];
- int which=0;
-
- EDITED;
- if(!strcmp(cmd,"objectcount")) { sprintf(resStr, "%d", [glist count]); return resStr; }
- if(!strncmp(cmd,"getobject",9)) {
- int num;
- sscanf(cmd,"%*s %d", &num);
- if(num>=0 && num<[glist count])
- {
- return [[glist objectAt:num] giveDescription]; }
- }
- if(!strncmp(cmd,"changeobject",12)) which=1; else if(!strncmp(cmd,"addobject",9)) which=2;
-
- if(which)
- {
- int type, num;
- if(result) NXCloseMemory(result, NX_TRUNCATEBUFFER);
- result=NXOpenMemory(cmd, strlen(cmd), NX_READONLY);
- if(which==2) NXScanf(result, "addobject %d",&type);
- else
- NXScanf(result, "changeobject %d %d",&num, &type);
- [self deselectAll:self];
- if(which==2)
- {
- switch(type)
- {
- case 0: CUR=[PencilGraphic alloc]; break;
- case 1: CUR=[PencilText alloc]; break;
- }
- }
- else
- if(num>=0 && num<[glist count])
- CUR=[glist objectAt:num];
- IFCUR
- {
- [CUR initFromDescription:result];
- curGrPos=[glist count];
- if(which==2) [glist addObject:CUR];
- [CUR calculateBoundingBox:self];
- CUR=nil;
- sprintf(resStr, "%d", curGrPos);
- curGrPos=-1;
- return resStr;
- }
- }
- if(!strcmp(cmd, "display")) {
- [self displayWithCurrentGraphic];
- return "1";
- }
- if(!strncmp(cmd, "resize", 6)) {
- NXRect f;
- sscanf(cmd, "resize %f %f %f %f", &f.origin.x, &f.origin.y, &f.size.width, &f.size.height);
- [window placeWindowAndDisplay:&f];
- return "1";
- }
- if(!strncmp(cmd, "save", 4)) {
- char name[400];
- sscanf(cmd, "save %s", name);
- [self doSave:name];
- return "1";
- }
- if(!strcmp(cmd, "selection")) {
- int len;
- int maxlen;
- char *buf;
-
- if(result) NXCloseMemory(result, NX_TRUNCATEBUFFER);
- result=NXOpenMemory(NULL,0,NX_WRITEONLY);
- IFCUR {
- if([CUR isMemberOf:[MultipleSelection class]]) {
- id slist;
- int i;
-
- slist=[CUR slist];
- for(i=0;i<[slist count];i++) {
- NXPrintf(result, "%d ", [glist indexOf:[slist objectAt:i]]);
- }
- } else {
- NXPrintf(result, "%d", curGrPos);
- }
- }
- else
- NXPrintf(result, "");
- NXGetMemoryBuffer(result, &buf, &len, &maxlen);
- return buf;
- }
- if(!strncmp(cmd, "delete", 6)) {
- int num;
-
- sscanf(cmd, "delete %d", &num);
- [self deselectAll:self];
- [glist removeObjectAt:num];
- return "1";
- }
- if(!strcmp(cmd, "print")) {
- [self printPSCode:self];
- return "1";
- }
- if(!strcmp(cmd, "name")) {
- if(docname)
- return docname;
- else
- return "";
- }
- if(!strncmp(cmd,"move",4)) {
- float dx, dy;
-
- sscanf(cmd, "move %f %f", &dx, &dy);
- [self translate:dx:dy];
- return "1";
- }
- if(!strncmp(cmd,"scale",5)) {
- float dx;
-
- sscanf(cmd, "scale %f", &dx);
- [self scale:dx/scale:dx/scale];
- scale=dx;
- return "1";
- }
- if(!strcmp(cmd,"paste")) {
- [self paste:self];
- return "1";
- }
- if(!strncmp(cmd, "select1",7)) {
- int i;
-
- sscanf(cmd, "select1 %d", &i);
- IFCUR { [CUR select:NO]; CUR=nil; curGrPos=-1; }
- if(i>=0 && i<[glist count]) { [CUR=[glist objectAt:i] select:YES]; curGrPos=i; }
- return "1";
- }
- if(!strncmp(cmd, "select",6)) {
- int i, c=[glist count];
-
- if(result) NXCloseMemory(result, NX_TRUNCATEBUFFER);
- result=NXOpenMemory(cmd, strlen(cmd), NX_READONLY);
-
- NXScanf(result, "select");
- IFCUR { [CUR select:NO]; CUR=nil; curGrPos=-1; }
- while(NXScanf(result, " %d", &i)==1) {
- if(i>=0 && i<c)
- {
- IFCUR { [CUR addToSelection:[[glist objectAt:i] select:YES] posFromEnd:0]; }
- else
- { [CUR=[MultipleSelection alloc] initWithGraphic:[[glist objectAt:i] select:YES]]; }
- }
- }
- [CUR calculateBoundingBox:self];
- return "1";
- }
- if(!strcmp(cmd, "group")) {
- [self makeGroup];
- [CUR setGroupType:PENCIL_STANDARD_GROUP];
- return "1";
- }
- if(!strcmp(cmd, "ungroup")) {
- [self ungroup];
- return "1";
- }
- if(!strcmp(cmd,"clipgroup")) {
- [self makeClipGroup:self];
- return "1";
- }
- if(!strcmp(cmd, "front")) {
- [self toFront:self];
- return "1";
- }
- if(!strcmp(cmd, "back")) {
- [self toBack:self];
- return "1";
- }
- if(!strcmp(cmd, "copyPS")) {
- [self copyAsPostScript:self];
- return "1";
- }
- if(!strncmp(cmd, "import",6)) {
- char name[400];
- float x,y;
-
- sscanf(cmd, "import %s %f %f", name, &x, &y);
- [self importImageFromFile:name:x:y];
- return "1";
- }
- return "failed";
- }
- @end
-